#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <pthread.h>

#include <audio_agc.h>
#include "testopt.h"
#include "audio_process.h"

#define AUDIO_BUF_SIZE 800

extern TEST_ARGS testArgs;
extern char fileName[NAME_BUF_SIZE];

static char inFileName[256] = "test_agc.pcm";
static char outFileName[256] = "test_agc_result.pcm";

static int sampleRate = 16000;

IMPAudioAgcConfig agcConfig = {
					.TargetLevelDbfs = 0,
					.CompressionGaindB = 6

};

typedef void Handle_agc;
static Handle_agc *handle_ao_agc = NULL;
uint32_t agc_sample_o = 0;

static void *audio_AGC_thread(void *argv)
{
	char *srcName = inFileName;
	char *dstName = outFileName;

	FILE *fpSrc = fopen(srcName,"r");
	FILE *fpDst = fopen(dstName,"w");

	if(NULL == fpSrc||NULL == fpDst){
		printf("open file %s or %s failed\n",srcName,dstName);
		return NULL;
	}

	AgcConfig config;
	config.targetLevelDbfs = agcConfig.TargetLevelDbfs;
	config.compressionGaindB = agcConfig.CompressionGaindB;
	config.limiterEnable = 1;

	handle_ao_agc = audio_process_agc_create();
	if(NULL == handle_ao_agc){
		printf("WebRtcAgc_Create error\n");
		return NULL;
   }

	switch(sampleRate){
		case 8000:
			agc_sample_o = 80;
			break;
		case 16000:
		case 32000:
		case 48000:
			agc_sample_o = 160;
			break;
		default:
			printf("WebRtc do not support samplerate: %d\n",sampleRate);
			return NULL;
			break;
	}
	int ret = -1;
	ret = audio_process_agc_set_config(handle_ao_agc,0,255,AgcModeAdaptiveDigital,sampleRate,config);
	int size = 0;
	int outMicLevel = 0;
	int count = 0;

	unsigned char saturationWarning = 0;
	char *pcm_buf = NULL;
	pcm_buf = (char *)malloc(AUDIO_BUF_SIZE);
	if (NULL == pcm_buf){
		printf("malloc pcm_buf space failed\n");
		return NULL;
	}

	while(1){
		size = fread(pcm_buf,1,AUDIO_BUF_SIZE,fpSrc);
			printf("size = %d\n",size);
			if (size <= 0){
				break;
			}
		ret = Agc_Process(handle_ao_agc,(short *)pcm_buf,agc_sample_o,(short*)pcm_buf,127,&outMicLevel,0,&saturationWarning,size);
		if (ret != 0){
			printf("Agc_Process ao error.\n");
			return NULL;
		}
		count++;
		printf("count= %d\n",count);
		fwrite(pcm_buf,1,size,fpDst);
	}
   printf("count = %d\n",count);
   printf("Agc process over\n");

	free(pcm_buf);
	fclose(fpSrc);
	fclose(fpDst);
	pcm_buf = NULL;
	fpSrc = NULL;
	fpDst = NULL;

	pthread_exit(0);
}

static void set_agcTest_param(TEST_ARGS *pTestArgs)
{
	if(NULL == pTestArgs) {
		printf("fun:%s,pTestArgs is empty.\n",__func__);
		return ;
	}
	if(strcmp(pTestArgs->inFileName,"") != 0)
		strncpy(inFileName,pTestArgs->inFileName,MAX_FILE_NAME_LEN);

	if(strcmp(pTestArgs->outFileName,"") != 0)
		strncpy(outFileName,pTestArgs->outFileName,MAX_FILE_NAME_LEN);

	if(pTestArgs->sampleRate > 0)
		sampleRate = pTestArgs->sampleRate;
}

int main(int argc,char *argv[])
{
   int ret = -1;

	ret = parse_param(argc,argv);
	if(1 == ret) {
		return 0;
	}
	if(ret < 0) {
		printf("parse_param failed\n");
		return -1;
	} else {
		printf("parse_param Ok\n");
	}

	set_agcTest_param(&testArgs);

	printf("This test parameter are as follows:\n\n");
	printf("inFileName = %s\n",inFileName);
	printf("outFileName = %s\n",outFileName);
	printf("sampleRate = %d\n",sampleRate);

	printf("[INFO]:Start to audio AGC test\n");
	printf("[INFO]:Please input any key to continue.\n");
	getchar();

	pthread_t agc_thread_id;
	ret = pthread_create(&agc_thread_id,NULL,audio_AGC_thread,NULL);
	if(ret != 0) {
		printf("create audio_AGC_thread failed\n");
		return -1;
	}

	pthread_join(agc_thread_id,NULL);

	printf("Finished agc thread.\n");

	return 0;

}
